package cmd

import (
	"fmt"
	"github.com/spf13/cobra"
	//"github.com/spf13/viper"
	crypto2 "blueprint-crypto/internal/crypto"
	"io"
	"os"
)

var (
	msgFile        string
	pemPrefix      string
	pemFile        string
	outFile        string
	EncryptionBits int
	keyWord        string
	newKeyword     string
	pwdfile        string
)

func NewDefaultCommand() *cobra.Command {
	return newCommand(os.Stdin, os.Stdout, os.Stderr)
}

func newCommand(in io.Reader, out, err io.Writer) *cobra.Command {
	cmds := &cobra.Command{
		Use:   "blueprint-crypto",
		Short: "blueprint-crypto 文件加解密工具",
		Run:   runHelp,
	}
	cmds.AddCommand(getVersion())
	cmds.AddCommand(runEncryptionByRSA())
	cmds.AddCommand(runDecryptionByRSA())
	cmds.AddCommand(generateRSAKey())
	cmds.AddCommand(runBatchEncryptionByRSA())
	cmds.AddCommand(runBatchDecryptionByRSA())
	cmds.AddCommand(runBatchEncryptionYamlByRSA())
	cmds.AddCommand(runBatchDecryptionYamlByRSA())
	cmds.AddCommand(runBatchEncryptionByAES())
	cmds.AddCommand(runBatchDecryptionByAES())
	//flags := cmds.PersistentFlags()
	//addRootFlag(flags)
	return cmds
}

//func addRootFlag(fs *pflag.FlagSet) {
//	fs.StringVarP(&msgFile, "file", "f", "", "指向需要加解密的文件")
//	fs.StringVarP(&pemFile, "pemFile", "p", "", "加解密需要的密钥文件")
//	fs.StringVarP(&outFile, "outFile", "u", "", "加解密输出的文件")
//}

func getVersion() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "version",
		Short: "版本",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println(`blueprint v1.1.0`)
		},
	}
	return cmd
}

func runHelp(cmd *cobra.Command, args []string) {
	cmd.Help()
}

// 生成密钥对，保存到文件
func generateRSAKey() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "generateRSAKey",
		Short: "生成RSA密钥",
		Long:  `Description: 生成密钥对，默认2048位`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.GenerateRSAKey(EncryptionBits, pemPrefix)
		},
	}
	cmd.Flags().StringVarP(&pemPrefix, "pemPrefix", "r", "", "生成密钥文件的前缀")
	cmd.Flags().IntVarP(&EncryptionBits, "encryptionBits", "b", 2048, "加密位数")
	cmd.MarkFlagRequired("pemPrefix")
	cmd.Example = "blueprint-crypto generateRSAKey -b 2048 -prefix demo"
	return cmd
}

// 加密
func runEncryptionByRSA() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "encryptionRSA",
		Short: "RSA文件加密",
		Long:  `Description: 文件RSA加密`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.RSA_Encrypt(msgFile, pemFile, outFile)

		},
	}
	cmd.Flags().StringVarP(&msgFile, "file", "f", "", "指向需要加解密的文件")
	cmd.Flags().StringVarP(&pemFile, "pemFile", "p", "", "加密需要的RSA公钥文件")
	cmd.Flags().StringVarP(&outFile, "outFile", "u", "", "加密输出的文件")
	cmd.MarkFlagRequired("file")
	cmd.MarkFlagRequired("pemFile")
	cmd.MarkFlagRequired("outFile")
	cmd.Example = "blueprint-crypto encryptionRSA -f demo.txt -p demo-public.pem -u cipherfile"
	return cmd
}

// 解密
func runDecryptionByRSA() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "decryptionRSA",
		Short: "RSA文件解密",
		Long:  `Description: 文件RSA解密`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.RSA_Decrypt(msgFile, pemFile, outFile)
		},
	}
	cmd.Flags().StringVarP(&msgFile, "file", "f", "", "指向需要加解密的文件")
	cmd.Flags().StringVarP(&pemFile, "pemFile", "p", "", "解密需要的RSA私钥文件")
	cmd.Flags().StringVarP(&outFile, "outFile", "u", "", "解密输出的文件")
	cmd.MarkFlagRequired("file")
	cmd.MarkFlagRequired("pemFile")
	cmd.MarkFlagRequired("outFile")
	cmd.Example = "blueprint-crypto decryptionRSA -f cipherfile -p demo-private.pem -u plainfile"
	return cmd
}

// 批量加密
func runBatchEncryptionByRSA() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "batchencryptRSA",
		Short: "RSA批量文件加密",
		Long:  `Description: 批量文件RSA加密`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.BatchRSA_Encrypt(msgFile, pemFile, keyWord, newKeyword)

		},
	}
	cmd.Flags().StringVarP(&msgFile, "filepath", "f", "", "指向需要加密的文件夹")
	cmd.Flags().StringVarP(&pemFile, "pemFile", "p", "", "加密需要的RSA公钥文件")
	cmd.Flags().StringVarP(&keyWord, "keyWord", "k", "", "加密需要的密钥文件名的关键字")
	cmd.Flags().StringVarP(&newKeyword, "newKeyword", "n", "", "加解密输出的文件名的关键字")
	cmd.MarkFlagRequired("filepath")
	cmd.MarkFlagRequired("pemFile")
	cmd.MarkFlagRequired("keyWord")
	cmd.MarkFlagRequired("newKeyword")
	cmd.Example = "blueprint-crypto batchencryptRSA  -f ./test -p demo-public.pem -k secret -n new"
	return cmd
}

// 批量解密
func runBatchDecryptionByRSA() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "batchdecryptRSA",
		Short: "RSA批量文件解密",
		Long:  `Description: 批量文件RSA解密`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.BatchRSA_Decrypt(msgFile, pemFile, keyWord, newKeyword)

		},
	}
	cmd.Flags().StringVarP(&msgFile, "filepath", "f", "", "指向需要解密的文件夹")
	cmd.Flags().StringVarP(&pemFile, "pemFile", "p", "", "解密需要的RSA私钥文件")
	cmd.Flags().StringVarP(&keyWord, "keyWord", "k", "", "解密需要的密钥文件名的关键字")
	cmd.Flags().StringVarP(&newKeyword, "newKeyword", "n", "", "解密输出的文件名的关键字")
	cmd.MarkFlagRequired("filepath")
	cmd.MarkFlagRequired("pemFile")
	cmd.MarkFlagRequired("keyWord")
	cmd.MarkFlagRequired("newKeyword")
	cmd.Example = "blueprint-crypto batchdecryptRSA  -f ./test -p demo-public.pem -k secret -n new"
	return cmd
}

// 批量加密YAML
func runBatchEncryptionYamlByRSA() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "batchencryptyamlRSA",
		Short: "RSA批量YAML文件字段加密",
		Long:  `Description: 批量YAML文件password字段RSA加密`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.BatchRSA_Encrypt_yaml(msgFile, pemFile, keyWord)

		},
	}
	cmd.Flags().StringVarP(&msgFile, "filepath", "f", "", "指向需要加密的文件夹")
	cmd.Flags().StringVarP(&pemFile, "pemFile", "p", "", "加密需要的RSA公钥文件")
	cmd.Flags().StringVarP(&keyWord, "keyWord", "k", "", "加密需要的密钥文件名的关键字")
	cmd.MarkFlagRequired("filepath")
	cmd.MarkFlagRequired("pemFile")
	cmd.MarkFlagRequired("keyWord")
	cmd.Example = "blueprint-crypto batchencryptyamlRSA  -f ./test -p demo-public.pem -k yaml"
	return cmd
}

// 批量解密YAML
func runBatchDecryptionYamlByRSA() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "batchdecryptyamlRSA",
		Short: "RSA批量YAML文件字段解密",
		Long:  `Description: 批量YAML文件password字段RSA解密`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.BatchRSA_Decrypt_yaml(msgFile, pemFile, keyWord)
		},
	}
	cmd.Flags().StringVarP(&msgFile, "filepath", "f", "", "指向需要解密的文件夹")
	cmd.Flags().StringVarP(&pemFile, "pemFile", "p", "", "解密需要的RSA私钥文件")
	cmd.Flags().StringVarP(&keyWord, "keyWord", "k", "", "解密需要的密钥文件名的关键字")
	cmd.MarkFlagRequired("filepath")
	cmd.MarkFlagRequired("pemFile")
	cmd.MarkFlagRequired("keyWord")
	cmd.Example = "blueprint-crypto batchdecryptyamlRSA  -f ./test -p demo-private.pem -k yaml "
	return cmd
}

// 批量加密
func runBatchEncryptionByAES() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "batchencryptAES",
		Short: "AES批量文件加密",
		Long:  `Description: 批量文件AES加密`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.BatchAES_Encrypt(msgFile, pwdfile, pemFile, keyWord, newKeyword)

		},
	}
	cmd.Flags().StringVarP(&msgFile, "filepath", "f", "", "指向需要加密的文件夹")
	cmd.Flags().StringVarP(&pwdfile, "pwdfile", "d", "", "AES加密需要的pwd密钥文件")
	cmd.Flags().StringVarP(&pemFile, "pemFile", "p", "", "解密PWD密钥文件需要的RSA私钥")
	cmd.Flags().StringVarP(&keyWord, "keyWord", "k", "", "加密需要的密钥文件名的关键字")
	cmd.Flags().StringVarP(&newKeyword, "newKeyword", "n", "", "加解密输出的文件名的关键字")
	cmd.MarkFlagRequired("filepath")
	cmd.MarkFlagRequired("pwdfile")
	cmd.MarkFlagRequired("pemFile")
	cmd.MarkFlagRequired("keyWord")
	cmd.MarkFlagRequired("newKeyword")
	cmd.Example = "blueprint-crypto batchencryptAES  -f ./test -d aespwd.key -p demo-private.pem -k secret -n new"
	return cmd
}

// 批量解密
func runBatchDecryptionByAES() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "batchdecryptAES",
		Short: "AES批量文件解密",
		Long:  `Description: 批量文件AES解密`,
		Run: func(cmd *cobra.Command, args []string) {
			crypto2.BatchAES_Decrypt(msgFile, pwdfile, pemFile, keyWord, newKeyword)

		},
	}
	cmd.Flags().StringVarP(&msgFile, "filepath", "f", "", "指向需要解密的文件夹")
	cmd.Flags().StringVarP(&pwdfile, "pwdfile", "d", "", "AES加密需要的pwd密钥文件")
	cmd.Flags().StringVarP(&pemFile, "pemFile", "p", "", "解密PWD密钥文件需要的RSA私钥")
	cmd.Flags().StringVarP(&keyWord, "keyWord", "k", "", "解密需要的密钥文件名的关键字")
	cmd.Flags().StringVarP(&newKeyword, "newKeyword", "n", "", "解密输出的文件名的关键字")
	cmd.MarkFlagRequired("filepath")
	cmd.MarkFlagRequired("pwdfile")
	cmd.MarkFlagRequired("pemFile")
	cmd.MarkFlagRequired("keyWord")
	cmd.MarkFlagRequired("newKeyword")
	cmd.Example = "blueprint-crypto batchdecryptAES  -f ./test -d aespwd.key -p demo-private.pem -k new -n secret"
	return cmd
}
